package onTheFly;

import java.io.File;
import java.io.ObjectInputStream.GetField;
import java.util.ArrayList;
import java.util.BitSet;
import java.util.Iterator;

import encodingSimulation.EncodingHelper;
import encodingSimulation.EncodingImplementation;

public class InitialServerSet {
	
	public static void main(String[] args) {
//		int k = 6;
//		int n = 20;
		HelperClass helper = null;
		OnTheFlyInitialServer initialServer;

		

//		int[][] generator = helper.createGeneratorMatrix();
		// int[][] generator={ {1 ,1, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1,
		// 1, 1, 1, 1},
		// {1 ,0 ,0 ,0 ,1 ,1 ,1 ,0 ,0 ,1 ,0 ,1 ,0 ,0 ,1 ,0 ,1 ,0 ,0, 0},
		// {0 ,0, 1, 1, 1, 0, 0, 1 ,1 ,1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 1},
		// {1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0 ,0 ,0},
		// {0, 1, 0, 0, 0, 1, 1, 0, 0 ,0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0},
		// {1 ,1 ,1 ,0 ,1 ,0 ,1 ,1 ,0 ,1 ,1 ,1 ,0 ,0 ,1 ,1 ,1 ,0 ,1 ,1},
		// {0 ,0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0},
		// {1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1}};
		// helper.printMatrix(generator, k, n);
		/******
		 * include the code for encoding here
		 */
		File filename = new File("C:" + File.separator + "Users"
				+ File.separator + "Bhavya" + File.separator + "Desktop"
				+ File.separator + "java_for_cloudcomputing" + File.separator
				+ "java_code" + File.separator + "Sample.doc.txt");
		
		File createdFilename = new File("C:" + File.separator + "Users"
				+ File.separator + "Bhavya" + File.separator + "Desktop"
				+ File.separator + "java_for_cloudcomputing" + File.separator
				+ "java_code" + File.separator + "ObtainedSampleOFG.doc.txt");
		String checksum1 = null, checksum2 = null, checksum3 = null;
		double Reliability = .999999999999;
		int numberOfSourceFragments = 128;
		double serverAvailabilityProbability = .9;
		int OPTIONFORGENERATOR = 1;
		int[][] generatorMatrix;
		ArrayList<BitSet> encodedFragments = new ArrayList<BitSet>();
		ArrayList<BitSet> sourceBits = new ArrayList<BitSet>();
		EncodingImplementation encoder = new EncodingImplementation();
		EncodingHelper eHelper = new EncodingHelper(encoder);
		/**
		 * set values of parameters
		 */
		encoder.setFileName(filename);
		encoder.setReliability(Reliability);
		encoder.setNumberOfSourceFragments(numberOfSourceFragments);
		encoder.setServerAvailabilityProbability(serverAvailabilityProbability);
		
		sourceBits = eHelper.fragmentSourceData(filename);
		generatorMatrix = eHelper.createGeneratorMatrix(OPTIONFORGENERATOR);
		encodedFragments = encoder.createEncodedPackets(sourceBits,
				generatorMatrix);
		
		int k = encoder.getNumberOfSourceFragments();
		int n = encoder.getTotalEncodedPackets();
		
		helper = new HelperClass(k,n );
		initialServer = new OnTheFlyInitialServer(k, n);
		/************
		 * Part of the decoding is present here include the code to pass encoded
		 * fragments also to test if inverse of OFG obtained by performing the
		 * same operation solves the questions to get the correct source frags
		 **************/
		int[][] transpose = helper.matrixTranspose(generatorMatrix);

		int[] index = initialServer.onTheFlyServer(transpose,
				helper.identity(k));
		int canProceed = helper.gaussianElimination(transpose, index);
		System.out.println("Linearly independent"+canProceed);
		// int canProceed=1;

		int[] serverAvailability = helper.serverAvailability();
		// int[] serverAvailability={1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 0, 1,
		// / 1, 1, 1, 1, 0, 1};
		System.out.println();
		for (int i : serverAvailability) {
			System.out.print(" " + i);
		}

		int serverCount = k, currentServerCount = 0;

		if (canProceed == 1) {
			canProceed = 0;
			while (currentServerCount < serverCount) {
				for (int serverNumber : index) {
					System.out.println(" svrNbr" + serverNumber + ":"
							+ serverAvailability[serverNumber]);
					if (serverAvailability[serverNumber] == 1) {
						currentServerCount++;
					} else {
						/*
						 * find out another server in place of this missing
						 * server" serverNumber"
						 */
						currentServerCount = 0;
						index = initialServer.onNextSetOfServerVer2(transpose,
								serverNumber, helper.identity(k));
						System.out.println("Linearly independent"+helper.gaussianElimination(transpose, index));
						break;
					}
				}
			}
		}// end of above if loop
//		ArrayList<BitSet> subsetEncodedFragments= new ArrayList<BitSet>();
//		for ( int i : index){
//			BitSet temp= encodedFragments.get(i);
//			subsetEncodedFragments.add(temp);
//		}
//		System.out.println(subsetEncodedFragments.size());
	ArrayList<BitSet> obtainedSourceFragments=initialServer.decodePacketsVer2(encodedFragments, transpose, k, n, index);
	StringBuffer obtainedSource = new StringBuffer();
	Iterator<BitSet> iter2 = obtainedSourceFragments.iterator();
	while (iter2.hasNext()) {
		obtainedSource.append(new String(iter2.next().toByteArray()));
	}
	eHelper.writeToFile(createdFilename, obtainedSource.toString());
	try {
		checksum1 = eHelper.getMD5Checksum(filename);
		checksum2 = eHelper.getMD5Checksum(createdFilename);
	} catch (Exception e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
	if (checksum1.equals(checksum2)) {

		System.out.println(" The checksum is the same(ofg); data equal");
	}else {
		System.out.println(" big big trouble");
	}
	

	}// end of main
}
